//! HTTP处理器，集成被动扫描功能

use async_trait::async_trait;
use mitm_core::hyper::{Body, Request, Response};
use mitm_core::handler::{HttpHandler};
use mitm_core::mitm::{HttpContext, RequestOrResponse};
use passive_scan::{PassiveScanEngine, HttpEvent};
use rule::{RuleHttpHandler, RuleHandlerCtx};
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Instant;
use log::{debug, info};
use tokio;

/// 集成了被动扫描的HTTP处理器
/// HTTP事件提取器，用于处理和过滤HTTP事件
pub struct HttpEventExtractor;

impl HttpEventExtractor {
    /// 判断是否应该跳过某个事件（如静态资源）
    pub fn should_skip_event(event: &HttpEvent) -> bool {
        // 简单的静态资源检测逻辑
        let static_extensions = [
            ".css", ".js", ".jpg", ".jpeg", ".png", ".gif", 
            ".ico", ".svg", ".woff", ".woff2", ".ttf", ".eot",
            ".mp4", ".mp3", ".webm", ".ogg", ".mov", ".avi",
            ".pdf", ".zip", ".rar", ".tar", ".gz", ".7z"
        ];
        
        for ext in static_extensions.iter() {
            if event.url.ends_with(ext) {
                return true;
            }
        }
        
        false
    }
}

#[derive(Clone)]
pub struct ScanHttpHandler {
    /// 原始的规则处理器
    rule_handler: RuleHttpHandler,
    /// 被动扫描引擎
    scan_engine: Arc<PassiveScanEngine>,
    /// 连接计数器
    counter: Arc<AtomicU64>,
}

impl ScanHttpHandler {
    /// 创建新的扫描HTTP处理器
    pub fn new(rule_handler: RuleHttpHandler, scan_engine: Arc<PassiveScanEngine>) -> Self {
        Self {
            rule_handler,
            scan_engine,
            counter: Arc::new(AtomicU64::new(0)),
        }
    }

    /// 简单的连接ID生成函数
    fn generate_connection_id(&self) -> String {
        let id = self.counter.fetch_add(1, Ordering::Relaxed);
        format!("conn_{}_{}", id, Instant::now().elapsed().as_millis())
    }
}

#[async_trait]
impl HttpHandler<RuleHandlerCtx> for ScanHttpHandler {
    async fn handle_request(
        &self,
        ctx: &mut HttpContext<RuleHandlerCtx>,
        req: Request<Body>,
    ) -> RequestOrResponse {
        // 在后台记录扫描信息，不阻塞主流程
        let scan_engine = self.scan_engine.clone();
        let method = req.method().clone();
        let uri = req.uri().clone();
        let headers = req.headers().clone();
        
        tokio::spawn(async move { 
            debug!("Scanning request: {} {}", method, uri);
            
            // 触发测试告警 - 密码泄露
            if uri.path() == "/test-alert" {
                info!("🚨 触发测试告警: 密码泄露检测");
                let mut headers_map = HashMap::new();
                let response_body = r#"{"user": "admin", "password": "secret123456", "api_key": "sk_live_1234567890abcdef1234567890abcdef"}"#;
                
                let event = HttpEvent::new_response(
                    200,
                    headers_map,
                    response_body.to_string(),
                    uri.to_string(),
                    method.to_string()
                );
                
                if let Ok(results) = scan_engine.process_event(event).await {
                    for result in results {
                        info!("🚨 发现安全问题: {} - 严重程度: {:?} - URL: {}", 
                            result.title, result.severity, result.url);
                    }
                }
            }
            
            // 创建HTTP事件
            let mut headers_map = HashMap::new();
            for (key, value) in headers.iter() {
                if let Ok(value_str) = value.to_str() {
                    headers_map.insert(key.to_string(), value_str.to_string());
                }
            }
            
            // 注意：实际场景中需要从req.body()读取body内容
            let body = String::new();
            let source_ip = "client".to_string();
            
            // 创建并处理HTTP事件
            let event = HttpEvent::new_request(
                method, uri, headers_map, body, source_ip
            );
            
            // 处理事件并记录结果
            if let Ok(results) = scan_engine.process_event(event).await {
                debug!("Request scan completed, found {} issues", results.len());
            }
        });

        // 直接调用原始处理器
        self.rule_handler.handle_request(ctx, req).await
    }

    async fn handle_response(
        &self,
        ctx: &mut HttpContext<RuleHandlerCtx>,
        res: Response<Body>,
    ) -> Response<Body> {
        // 克隆必要的数据，因为res会被消费
        let status_code = res.status().as_u16();
        let headers = res.headers().clone();
        let scan_engine = self.scan_engine.clone();
        let connection_id = self.generate_connection_id();
        
        // 在后台记录扫描信息，不阻塞主流程
        tokio::spawn(async move { 
            debug!("[Scan] Processing response for connection: {}, status: {}", 
                   connection_id, status_code);
            
            // 创建HTTP事件
            let mut headers_map = HashMap::new();
            for (key, value) in headers.iter() {
                if let Ok(value_str) = value.to_str() {
                    headers_map.insert(key.to_string(), value_str.to_string());
                }
            }
            
            // 注意：实际场景中需要从res.body()读取body内容
            let body = String::new();
            let request_url = "unknown".to_string(); // 需要从上下文获取
            let method = "unknown".to_string();     // 需要从上下文获取
            
            // 特殊测试路径 - 触发告警测试
            if request_url == "/test-alert" {
                info!("🚨 🚨 🚨 测试告警触发: 手动创建包含敏感信息的响应");
                
                // 创建包含多种敏感信息的测试响应体
                let test_body = r#"{
                    "user": "admin", 
                    "password": "secret123456",
                    "api_key": "sk_live_1234567890abcdef1234567890abcdef",
                    "db": "mysql://admin:db_password123@localhost:3306/users_db",
                    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsImV4cCI6MTY4ODQyMDQ5N30.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
                    "error": "SQL syntax error near 'SELECT * FROM users WHERE id=' OR 1=1' at line 1"
                }"#;
                
                // 创建测试事件
                let test_event = HttpEvent::new_response(
                    200,
                    headers_map.clone(),
                    test_body.to_string(),
                    request_url.clone(),
                    method.clone(),
                );
                
                // 处理测试事件
                info!("🔍 开始处理测试事件...");
                match scan_engine.process_event(test_event).await {
                    Ok(results) => {
                        info!("✅ 扫描完成! 发现 {} 个安全问题:", results.len());
                        for result in results {
                            info!("🚨 安全问题告警: {} - 严重程度: {:?} - URL: {}", 
                                result.title, result.severity, result.url);
                            info!("   证据: {}", result.evidence);
                        }
                    },
                    Err(e) => {
                        info!("❌ 扫描出错: {:?}", e);
                    }
                }
            }
            
            // 创建并处理HTTP事件
            let event = HttpEvent::new_response(
                status_code, headers_map, body, request_url, method
            );
            
            // 跳过静态资源
            if HttpEventExtractor::should_skip_event(&event) {
                debug!("[Scan] Skipping static resource: {}", event.url);
                return;
            }
            
            // 处理事件并记录结果
            if let Ok(results) = scan_engine.process_event(event).await {
                if !results.is_empty() {
                    info!("[VULN] Found {} vulnerabilities in connection: {}", 
                          results.len(), connection_id);
                    
                    #[cfg(feature = "fingerprint")]
                    info!("[Fingerprint] Feature enabled, fingerprinting active");
                    
                    for result in &results {
                        info!("[VULN] {} - {} (Severity: {:?})", 
                              result.title, result.url, result.severity);
                    }
                } else {
                    debug!("[Scan] No vulnerabilities found in connection: {}", 
                           connection_id);
                }
            }
        });

        // 直接调用原始处理器
        self.rule_handler.handle_response(ctx, res).await
    }
}



#[cfg(test)]
mod tests {
    use super::*;
    use rule::Rule;

    #[test]
    fn test_connection_manager() {
        // 直接测试ScanHttpHandler的generate_connection_id方法
        let handler = ScanHttpHandler::new(
            RuleHttpHandler::new(Arc::new(Vec::new())),
            Arc::new(PassiveScanEngine::new())
        );
        let id1 = handler.generate_connection_id();
        let id2 = handler.generate_connection_id();
        assert_ne!(id1, id2);
        assert!(id1.starts_with("conn_"));
        assert!(id2.starts_with("conn_"));
    }

    #[test]
    fn test_should_skip_event() {
        // 简化测试，只检查URL后缀匹配逻辑
        
        // 创建测试数据
        struct TestHttpEvent {
            url: String,
        }
        
        // 实现类似HttpEvent的结构用于测试
        impl TestHttpEvent {
            fn new(url: &str) -> Self {
                Self { url: url.to_string() }
            }
        }
        
        // 定义一个简化版的should_skip_event函数用于测试
        fn should_skip_test_event(event: &TestHttpEvent) -> bool {
            // 简单的静态资源检测逻辑
            let static_extensions = [
                ".css", ".js", ".jpg", ".jpeg", ".png", ".gif", 
                ".ico", ".svg", ".woff", ".woff2", ".ttf", ".eot",
                ".mp4", ".mp3", ".webm", ".ogg", ".mov", ".avi",
                ".pdf", ".zip", ".rar", ".tar", ".gz", ".7z"
            ];
            
            for ext in static_extensions.iter() {
                if event.url.ends_with(ext) {
                    return true;
                }
            }
            
            false
        }
        
        // 测试静态资源
        let static_event = TestHttpEvent::new("https://example.com/styles/main.css");
        assert!(should_skip_test_event(&static_event));
        
        // 测试API请求
        let api_event = TestHttpEvent::new("https://example.com/api/users");
        assert!(!should_skip_test_event(&api_event));
    }
}